package test.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.annotation.PostConstruct;

/**
 * 都是硬编码的，用户信息、权限。
 * <p>
 * Created by 张少昆 on 2017/12/23.
 */
@Configuration
@EnableWebSecurity
@Order( 2147483640 )
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @PostConstruct
    public void init(){
        System.out.println("test.config.SecurityConfig inited!");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{ //TODO 配置认证鉴权策略
        http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin();

        // http
        //         .csrf().disable() //默认是启用的
        //         .authorizeRequests().mvcMatchers().permitAll().anyRequest().authenticated();

        // http.authorizeRequests().antMatchers().permitAll().antMatchers().hasRole().anyRequest().authenticated();

        // http.formLogin().loginPage().failureForwardUrl().successForwardUrl().failureUrl().defaultSuccessUrl();
        // http.formLogin().defaultSuccessUrl(defaultSuccessUrl, true).failureUrl();//The default is "/login?error"

        // 使用handler，会覆盖默认的url跳转
        // http
        //         .formLogin()
        //         .loginPage(loginPage) //登陆页面（注意参数名）
        //         .failureHandler(failureHandler)
        //         .successHandler(successHandler);

    }

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception{ //TODO 配置认证鉴权信息来源，以及信息保存
        builder.inMemoryAuthentication().withUser("user").password("password").roles("USER"); //内存硬编码UserDetails对象
        builder.eraseCredentials(false);// TODO 认证后不抹除凭据信息！！
        // TODO 使用jdbc认证
        // builder.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery(usersByUsernameQuery).authoritiesByUsernameQuery(authoritiesByUsernameQuery).passwordEncoder(passwordEncoder).rolePrefix(rolePrefix);
        // TODO 使用userDetailsService认证！
        // builder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception{ //TODO 配置需要忽略的路径 - 和上面的http.xxx.permitAll()不同，这里直接被忽略。
        web.ignoring().antMatchers("/**/*.js", "/**/*.js.map", "/**/*.ts", "/**/*.css", "/**/*.css.map", "/**/*.png", "/**/*.gif", "/**/*.jpg", "/**/*.fco", "/**/*.woff", "/**/*.woff2", "/**/*.font", "/**/*.svg", "/**/*.ttf", "/**/*.pdf", "/*.ico", "/admin/api/**", "/404", "/401", "/403", "/error");
    }


    // TODO 下面这两个，不懂。嘛意思？为什么还要@Bean？  UserDetailsService完全可以@Service吧
    // protected UserDetailsService userDetailsService()
    // TODO 看说明，貌似是将protected void configure(AuthenticationManagerBuilder auth) throws Exception 中配置的UserDetailsService暴露出来。
    // 如果想要返回不同的UserDetailsService，需要同步更改userDetailsService方法！ -- 简而言之，可以不使用这两个方法！实际上，上面可能设置多个信息来源，但默认的service会一一查找吧
    // public UserDetailsService userDetailsServiceBean() throws Exception
}
